package buildinjava.ant;

import com.google.common.base.Function;
import com.google.common.collect.Iterators;
import java.util.AbstractMap;
import java.util.AbstractSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.apache.tools.ant.Project;

/**
 * Invokes Ant tasks.
 *
 * @author Gili Tzabari
 */
public final class Ant
{
	private final Project project;

	/**
	 * Creates a new Ant task.
	 * 
	 * @param project the Ant project
	 */
	public Ant(Project project)
	{
		this.project = project;
	}

	/**
	 * Returns the ant properties.
	 *
	 * @return the ant properties
	 */
	public Map<String, String> getProperties()
	{
		return new AbstractMap<String, String>()
		{
			@Override
			public Set<Entry<String, String>> entrySet()
			{
				return new AbstractSet<Entry<String, String>>()
				{
					@Override
					public Iterator<Entry<String, String>> iterator()
					{
						Iterator<?> source = project.getProperties().entrySet().iterator();
						return Iterators.transform(source, new Function<Object, Entry<String, String>>()
						{
							@Override
							@SuppressWarnings("unchecked")
							public Entry<String, String> apply(Object from)
							{
								return (Entry<String, String>) from;
							}
						});
					}

					@Override
					public int size()
					{
						return project.getProperties().size();
					}

					@Override
					public void clear()
					{
						project.getProperties().clear();
					}

					@Override
					@SuppressWarnings("element-type-mismatch")
					public boolean contains(Object o)
					{
						return containsKey(o);
					}
				};
			}

			@Override
			@SuppressWarnings("element-type-mismatch")
			public boolean containsKey(Object key)
			{
				return get(key) != null;
			}

			@Override
			public String get(Object key)
			{
				if (!(key instanceof String))
					return null;
				String safe = (String) key;
				return project.getProperty(safe);
			}

			@Override
			@SuppressWarnings("unchecked")
			public String put(String key, String value)
			{
				return (String) project.getProperties().put(key, value);
			}

			@Override
			public String remove(Object key)
			{
				return (String) project.getProperties().remove(key);
			}
		};
	}

	/**
	 * Sets the value of a property.
	 *
	 * @param name the property name
	 * @param value the property value
	 */
	public void setProperty(String name, String value)
	{
		project.setProperty(name, value);
	}
}
